﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Telerik.Windows.Controls;
using Microsoft.Phone.Controls.Maps;
using Confucius.entity;
using System.Windows.Media.Imaging;
using Confucius.daoImpl;
using System.Device.Location;
using Confucius.dao;
using Confucius.utils;
using System.IO.IsolatedStorage;

namespace Confucius.pages
{
    public partial class GamePlayPage : PhoneApplicationPage
    {
        private const string NORMAL_PLAY_BUTTON = "/Confucius;component/assets/ui/PlayNormal.png";
        private const string PRESSED_PLAY_BUTTON = "/Confucius;component/assets/ui/PlayPressed.png";

        MapLayer itemLayer;
        MapLayer questLayer;
        MapLayer npcLayer;
        List<Item> items;
        List<Quest> quests;
        List<NPC> npcs;
        BitmapImage itemSource;
        BitmapImage questSource;
        BitmapImage npcSource;

        public GamePlayPage()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(MainPage_Loaded);
        }

        private void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            string currentGameID = null;
            if (NavigationContext.QueryString.ContainsKey("currentGameID"))
                currentGameID = NavigationContext.QueryString["currentGameID"];
            if (currentGameID == null)
                return;

            items = new ItemDAOImpl().retreiveItems(currentGameID);
            quests = new QuestDAOImpl().retreiveQuests(currentGameID);
            npcs = new NPCDAOImpl().retrieveNPCs(currentGameID);

            PanoControl.Title = new GameDAOImpl(Application.Current as App).getLocalGameName(currentGameID);
            /*
             *  Quest tab
            */
            NPCListbox.ItemsSource = npcs;

            /*
             *  Inventory tab
            */
            ItemListbox.ItemsSource = items;
            PickableItemListbox.ItemsSource = items;

            /*
             *  Info tab
            */
            //gameInfoText.Text = new GameDAOImpl(Application.Current as App).readGameDetail(currentGameID).Introduction;

            /*
             *  Map tab
            */
            GeoCoordinate center = new GeoCoordinate(53.3414, -6.2603);
            map1.SetView(center, 16);
            /*
             *  Items layer
             */
            //Create a layer to contain the pushpin images.
            itemLayer = new MapLayer();
            map1.Children.Add(itemLayer);
            itemSource = new BitmapImage(new Uri("/Confucius;component/assets/images/item.png", UriKind.Relative));
            draw_Items_On_Map();

            /*
             *  Quests layer
             */
            //Create a layer to contain the pushpin images.
            questLayer = new MapLayer();
            map1.Children.Add(questLayer);
            questSource = new BitmapImage(new Uri("/Confucius;component/assets/images/quest.png", UriKind.Relative));
            draw_Quests_On_Map();
            /*
             *  NPC layer
             */
            //Create a layer to contain the pushpin images.
            npcLayer = new MapLayer();
            map1.Children.Add(npcLayer);
            npcSource = new BitmapImage(new Uri("/Confucius;component/assets/images/npc.png", UriKind.Relative));
            foreach (NPC npc in npcs)
            {
                Image pinImage = new Image();
                pinImage.Source = npcSource;
                //Define the image display properties.
                pinImage.Opacity = 0.8;
                pinImage.Stretch = System.Windows.Media.Stretch.None;
                npcLayer.AddChild(pinImage, new GeoCoordinate(npc.Lat, npc.Lng));
                pinImage.DataContext = npc;
                // Set on pin click event
                pinImage.MouseLeftButtonUp += new MouseButtonEventHandler(pin_MouseLeftButtonUp);
            }

        }

        private void pin_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            Object data = ((FrameworkElement)e.OriginalSource).DataContext;
            if (data is Item)
            {
                Item item = (Item)data;
                MessageBox.Show("It's an item.");
                ItemDAO itemDAO = new ItemDAOImpl();
                String itemStatus = itemDAO.readItemStatus(item.ItemID);
                if (itemStatus.Equals(Item.NOT_PICKABLE))
                {
                    MessageBox.Show("You have to unlock something to pick up this.");
                }
                else if (itemStatus.Equals(Item.PICKABLE))
                {
                    // Update item status in the list
                    int index = items.IndexOf(item);
                    item.Status = Item.PICKED;
                    items[index] = item;
                    // Store item status into database
                    itemDAO.updateItemStatus(item.ItemID, Item.PICKED);
                    MessageBox.Show("You have picked an item.");
                    // Update map pins
                    draw_Items_On_Map();

                    // Update list
                    updateViewLists();

                    // Check game rules
                    string gameID = "";
                    if (IsolatedStorageSettings.ApplicationSettings.Contains(Constants.CURRENT_GAMEID))
                    {
                        gameID = (string)IsolatedStorageSettings.ApplicationSettings[Constants.CURRENT_GAMEID];
                    }
                    GameRuleManager.getInstance(gameID).gameRuleCheck(item.ItemID, Condition.PICK_ITEM_CONDITION);
                    //GameOverlay.this.removeOverlay(element);
                }

            }
            else if (data is Quest)
            {
                Quest quest = ((Quest)data);
                QuestDAO questDAO = new QuestDAOImpl();
                //quest = questDAO.readQuest(quest.QuestID,gameID);
                MessageBox.Show("It's a quest, and " + quest.Title);
                if (quest.Status.Equals(Quest.NOT_CHECKED_IN_STATUS))
                {
                    //int finishHighestOrder  = context.getSharedPreferences(Constants.PREFS_NAME, 0).getInt("highestAvailableQuest", 0);
                    //if(finishHighestOrder + 1 == quest.getQuestOrder()) {
                    //Toast.makeText(context, "Quest" + quest.getQuestOrder() + " starts now.", Toast.LENGTH_LONG).show();

                    // Update item status in the list
                    int index = quests.IndexOf(quest);
                    quest.Status = Quest.START_STATUS;
                    quests[index] = quest;
                    // Store item status into database
                    questDAO.updateQuestStatus(quest.QuestID, Quest.START_STATUS);
                    MessageBox.Show("Check in this quest.");
                    // Update map pins
                    draw_Quests_On_Map();

                    // Update list
                    updateViewLists();

                    /* Start of Liangchuan's code
                     * Modified date: 16/04/2012
                     * Purpose: Save the questID to isolatedStorage
                     */

                    IsolatedStorageSettings.ApplicationSettings.Remove(Constants.CURRENT_QUESTID);
                    IsolatedStorageSettings.ApplicationSettings.Add(Constants.CURRENT_QUESTID, quest.QuestID);
                    IsolatedStorageSettings.ApplicationSettings.Save();

                    /* End of Liangchuan's code */
                    // Check game rules
                    string gameID = "";
                    if (IsolatedStorageSettings.ApplicationSettings.Contains(Constants.CURRENT_GAMEID))
                    {
                        gameID = (string)IsolatedStorageSettings.ApplicationSettings[Constants.CURRENT_GAMEID];
                    }
                    GameRuleManager.getInstance(gameID).gameRuleCheck(quest.QuestID, Condition.START_QUEST_CONDITION);
                    //} else {
                    //    Toast.makeText(context, "You have to finish the previous Quests first.", Toast.LENGTH_LONG).show();
                    //}
                }
            }
            else if (data is NPC)
            {
                talkMore_Click((NPC)data);
            }

        }

        private void updateViewLists() {
            NPCListbox.ItemsSource = null;
            ItemListbox.ItemsSource = null;
            PickableItemListbox.ItemsSource = null;

            string currentGameID = null;
            if (NavigationContext.QueryString.ContainsKey("currentGameID"))
                currentGameID = NavigationContext.QueryString["currentGameID"];
            if (currentGameID == null)
                return;

            items = new ItemDAOImpl().retreiveItems(currentGameID);
            quests = new QuestDAOImpl().retreiveQuests(currentGameID);
            npcs = new NPCDAOImpl().retrieveNPCs(currentGameID);

            NPCListbox.ItemsSource = npcs;
            ItemListbox.ItemsSource = items;
            PickableItemListbox.ItemsSource = items;

        }

        private void draw_All_On_Map() {
            draw_Items_On_Map();
            draw_Quests_On_Map();
        }

        private void draw_Items_On_Map()
        {
            string currentGameID = null;
            if (NavigationContext.QueryString.ContainsKey("currentGameID"))
                currentGameID = NavigationContext.QueryString["currentGameID"];
            if (currentGameID == null)
                return;

            itemLayer.Children.Clear();
            items = new ItemDAOImpl().retreiveItems(currentGameID);
            foreach (Item item in items)
            {
                // Hide picked items
                if (!item.Status.Equals(Item.PICKED))
                {
                    Image pinImage = new Image();
                    pinImage.Source = itemSource;
                    //Define the image display properties.
                    pinImage.Opacity = 0.8;
                    pinImage.Stretch = System.Windows.Media.Stretch.None;
                    itemLayer.AddChild(pinImage, new GeoCoordinate(item.Lat, item.Lng));
                    pinImage.DataContext = item;
                    // Set on pin click event
                    pinImage.MouseLeftButtonUp += new MouseButtonEventHandler(pin_MouseLeftButtonUp);
                }
            }

        }

        private void draw_Quests_On_Map()
        {
            string currentGameID = null;
            if (NavigationContext.QueryString.ContainsKey("currentGameID"))
                currentGameID = NavigationContext.QueryString["currentGameID"];
            if (currentGameID == null)
                return;

            questLayer.Children.Clear();
            quests = new QuestDAOImpl().retreiveQuests(currentGameID);
            foreach (Quest quest in quests)
            {
                if (quest.Status.Equals(Quest.NOT_CHECKED_IN_STATUS))
                {
                    Image pinImage = new Image();
                    pinImage.Source = questSource;
                    //Define the image display properties.
                    pinImage.Opacity = 0.8;
                    pinImage.Stretch = System.Windows.Media.Stretch.None;
                    questLayer.AddChild(pinImage, new GeoCoordinate(quest.Lat, quest.Lng));
                    pinImage.DataContext = quest;
                    // Set on pin click event
                    pinImage.MouseLeftButtonUp += new MouseButtonEventHandler(pin_MouseLeftButtonUp);
                }
            }
        }

        private void talkMore_Click(NPC npc)
        {
            NPCDAO npcDAO = new NPCDAOImpl();
            String status = npcDAO.readNPCStatus(npc.NpcID);

            if (status.Equals(NPC.NOT_CHATTABLE))
            {
                MessageBox.Show("You cannot talk with this NPC. It seems you have to unlock something.",
                    "Notice", MessageBoxButton.OK);
            }
            else
            {
                if (status.Equals(NPC.END_CHAT))
                {
                    MessageBox.Show("You've finished a chat to uncover something. Go on to find something else.",
                    "Notice", MessageBoxButton.OK);
                    return;
                }
                string url = "/pages/NPCTalkingPage.xaml?npcID=" + npc.NpcID + "&startDialogNodeID=" + npc.DialogID;
                Uri uri = new Uri(url, UriKind.Relative);
                NavigationService.Navigate(uri);
            }


        }

        private void buttonAerial_Click(object sender, RoutedEventArgs e)
        {
            map1.Mode = new AerialMode();
        }

        private void buttonRoad_Click(object sender, RoutedEventArgs e)
        {
            map1.Mode = new RoadMode();
        }

        private void buttonZoomIn_Click(object sender, RoutedEventArgs e)
        {
            double zoom;
            zoom = map1.ZoomLevel;
            map1.ZoomLevel = ++zoom;
        }

        private void buttonZoomOut_Click(object sender, RoutedEventArgs e)
        {
            double zoom;
            zoom = map1.ZoomLevel;
            map1.ZoomLevel = --zoom;
        }

        private void QuestListbox_Tap(object sender, GestureEventArgs e)
        {
            Quest data = ((FrameworkElement)e.OriginalSource).DataContext as Quest;
            NavigationService.Navigate(new Uri("/pages/Information.xaml?title=" + data.Title +
                "&text=" + data.StartText, UriKind.Relative));
        }

        private void ItemListbox_Tap(object sender, GestureEventArgs e)
        {
            Item data = ((FrameworkElement)e.OriginalSource).DataContext as Item;
            //NavigationService.Navigate(new Uri("/pages/Information.xaml?title=" + data.Title +
            //    "&text=" + data.DisplayText + "&iconid=" + data.ContainedMediaID, UriKind.Relative));
            NavigationService.Navigate(new Uri("/pages/ObjectDetailPage.xaml?itemID=" + data.ItemID, UriKind.Relative));
        }

        private void PickableItemListbox_Tap(object sender, GestureEventArgs e)
        {
            Item data = ((FrameworkElement)e.OriginalSource).DataContext as Item;
            //NavigationService.Navigate(new Uri("/pages/Information.xaml?title=" + data.Title +
            //    "&text=" + data.DisplayText + "&iconid=" + data.ContainedMediaID, UriKind.Relative));
            NavigationService.Navigate(new Uri("/pages/ObjectDetailPage.xaml?itemID=" + data.ItemID, UriKind.Relative));
        }

        private void NPCListbox_Tap(object sender, GestureEventArgs e)
        {
            NPC data = ((FrameworkElement)e.OriginalSource).DataContext as NPC;
            //NavigationService.Navigate(new Uri("/pages/Information.xaml?title=" + data.Name +
            //    "&text=" + data.Greeting + "&iconid=" + data.FigureID, UriKind.Relative));
            NavigationService.Navigate(new Uri("/pages/ObjectDetailPage.xaml?npcID=" + data.NpcID, UriKind.Relative));
        }

        private void PopulateCategories()
        {
            
        }

        private void PopulateProjects()
        {
            
        }

        private void SetOverdueState()
        {
            
        }

        private void PopulateTasks()
        {
            
        }

        private void NewProjectButton_Click(object sender, RoutedEventArgs e)
        {
            //NavigationService.Navigate(new Uri("/Views/EditProject.xaml", UriKind.Relative));
        }

        private void NewTaskButton_Click(object sender, RoutedEventArgs e)
        {
            //NavigationService.Navigate(new Uri("/Views/CreateTask.xaml", UriKind.Relative));
        }

        // Information page onClick event handler
        private void Info_Click(object sender, RoutedEventArgs e)
        {
            string currentGameID = null;
            if (IsolatedStorageSettings.ApplicationSettings.Contains(Constants.CURRENT_GAMEID))
            {
                currentGameID = (string)IsolatedStorageSettings.ApplicationSettings[Constants.CURRENT_GAMEID];
            }
            if (currentGameID == null)
            {
                return;
            }
            NavigationService.Navigate(new Uri("/pages/GameInfoPage.xaml", UriKind.Relative));
        }

        // Current quest page onClick event handler
        private void Checked_Click(object sender, RoutedEventArgs e)
        {
            string currentQuestID = null;
            if (IsolatedStorageSettings.ApplicationSettings.Contains(Constants.CURRENT_QUESTID))
            {
                currentQuestID = (string)IsolatedStorageSettings.ApplicationSettings[Constants.CURRENT_QUESTID];
            }
            if (currentQuestID == null)
            {
                MessageBox.Show("You need to check in a quest first.",
                    "Notice", MessageBoxButton.OK);
                //return;
                // For test purpose
                //IsolatedStorageSettings.ApplicationSettings.Remove(Constants.CURRENT_QUESTID);
                //IsolatedStorageSettings.ApplicationSettings.Add(Constants.CURRENT_QUESTID, "3fa41c7c-4f9a-447a-987f-dc6cc731ea84");
                //IsolatedStorageSettings.ApplicationSettings.Save();

            }
            NavigationService.Navigate(new Uri("/pages/CheckedQuestPage.xaml", UriKind.Relative));
        }

        // Finished quest(s) page onClick event handler
        private void Finished_Click(object sender, RoutedEventArgs e)
        {
            NavigationService.Navigate(new Uri("/pages/FinishedQuestsPage.xaml", UriKind.Relative));
        }

        private void AllProjects_Click(object sender, RoutedEventArgs e)
        {
            //NavigationService.Navigate(new Uri("/Views/AllProjects.xaml", UriKind.Relative));
        }

        private void TasksList_ItemTap(object sender, ListBoxItemTapEventArgs e)
        {
            
        }

        private void ProjectsList_ItemTap(object sender, ListBoxItemTapEventArgs e)
        {
            
        }

        private void CategoriesList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            
        }
    }
}
